<template>
  <a-modal
    :visible="visible"
    :title="roleOptTitle"
    :confirm-loading='confirmLoading'
    :destroyOnClose='true'
    centered
    :maskClosable="false"
    @ok='handleOk'
    @cancel='handleCancel'
  >
    <a-form-model ref="roleForm" :model="form" :rules="rules" v-bind="a">
      <a-form-model-item prop="name" label="角色名称">
        <a-input v-model="form.name" :disabled="this.isView" />
      </a-form-model-item>
      <a-form-model-item prop="powerIds" label="权限">
        <a-col :span="24" style="height: 600px; overflow: auto; border: 1px solid #f2f2f2;padding: 10px 0">
          <a-tree
            checkable
            :tree-data="treeData"
            v-model="form.powerIds"
            @check="onCheck"
          ></a-tree>
        </a-col>
      </a-form-model-item>
    </a-form-model>
  </a-modal>
</template>

<script>
import { TreeSelect, Tree } from 'ant-design-vue'
import { queryRoleDetail, updateRoleInfo, addRoleInfo } from '@/api/systemPersonnelManage'

const completeRoles = (data, tree) => {
  const d = [...data]
  const t = [...tree]
  t.forEach(v1 => {
    let p1 = v1.children
    p1.forEach(v2 => {
      let p2 = v2.children
      p2.forEach(v3 => {
        let p3 = v3.children
        if (p3 && p3.length > 0) {
          if (p3.filter(v => d.includes(v.key)).length > 0) {
            if (!d.includes(v3.key)) {
              d.push(v3.key)
            }
            if (!d.includes(v2.key)) {
              d.push(v2.key)
            }
            if (!d.includes(v1.key)) {
              d.push(v1.key)
            }
          }
        } else {
          if (p2.filter(v => d.includes(v.key)).length > 0) {
            if (!d.includes(v2.key)) {
              d.push(v2.key)
            }
            if (!d.includes(v1.key)) {
              d.push(v1.key)
            }
          }
        }
      })
    })
  })

  return d
}

const checkedPowerIds = (pidsStr, roleList) => {
  if (!pidsStr) return []
  pidsStr = `,${pidsStr},`
  roleList.forEach(v => {
    pidsStr = pidsStr.replace(`,${v.powerId},`, ',')
    v.childList.forEach(v2 => {
      pidsStr = pidsStr.replace(`,${v2.powerId},`, ',')
      const pages = v2.childList
      pages.forEach(v3 => {
        const opts = v3.childList
        if (opts && opts.length > 0) {
          pidsStr = pidsStr.replace(`,${v3.powerId},`, ',')
        }
      })
    })
  })

  const result = pidsStr.substr(1, pidsStr.length - 2).split(',')
  return result.map(v => parseInt(v))
}

export default {
  props: {
    editRoleId: '',
    isView: false,
    visible: false
  },
  data () {
    const power = (rule, value, callback) => {
      if (this.form.powerIds.length === 0) {
        callback(new Error('权限至少选择一个'))
      } else {
        callback()
      }
    }

    return {
      a: {labelCol: { span: 5 }, wrapperCol: { span: 16 }},
      roleOptTitle: '',
      confirmLoading: false,
      form: {
        name: '',
        powerIds: []
      },
      rules: {
        name: [{required: true, message: '角色姓名必须输入', trigger: 'blur'}, {max: 20, message: '角色姓名限制输入20个字符', trigger: 'blur'}],
        powerIds: [{required: true, validator: power, trigger: ['blur', 'change']}]
      },
      treeData: [],
      footer: true
    }
  },
  components: {
    [TreeSelect.name]: TreeSelect,
    [Tree.name]: Tree
  },
  methods: {
    onCheck (selectedKeys, info) {
      if (info.node.pos.split('-').length === 5) { // 操作层
        if (info.checked && info.node.title !== '查询' && !selectedKeys.includes(info.node.dataRef.mustCheckKey)) { // 其他操作选择，查询必选
          this.form.powerIds = selectedKeys.concat(info.node.dataRef.mustCheckKey)
        } else if (!info.checked && info.node.title === '查询') { // 查询取消后，清空其他
          this.form.powerIds = selectedKeys.filter(v => !info.node.dataRef.allKeys.includes(v))
        }
      }
    },
    handleTree (tree, rspData) {
      let mustCheckKey = null
      let tempArr = []
      let allKeys = []
      rspData.forEach(v => {
        let t = []
        if (v.childList && v.childList.length > 0) {
          t = this.handleTree(t, v.childList)
        }

        tempArr.push({
          title: v.name,
          key: v.powerId,
          value: v.powerId,
          disabled: this.isView,
          children: t
        })

        if (v.name === '查询') {
          mustCheckKey = v.powerId
        }
        allKeys.push(v.powerId)
      })
      tempArr = tempArr.map(v => ({...v, mustCheckKey, allKeys}))
      return tempArr
    },
    handleCancel () {
      this.$emit('set-visible', false)
      this.$refs['roleForm'].resetFields()
    },
    handleOk () {
      if (this.isView) {
        this.handleCancel()
        return
      }
      this.$refs.roleForm.validate(valid => {
        if (valid) {
          this.confirmLoading = true
          const roles = completeRoles(this.form.powerIds, this.treeData).join(',')
          if (this.editRoleId) {
            updateRoleInfo({name: this.form.name, powerIds: roles, roleId: this.editRoleId}).then(rsp => {
              this.$message.success('更新成功')
              this.$emit('set-visible', false)
              this.$emit('refresh-data')
              this.$refs['ruleForm'].resetFields()
              setTimeout(() => { this.confirmLoading = false }, 1000)
            }).catch(() => {
              this.confirmLoading = false
            })
          } else {
            addRoleInfo({name: this.form.name, powerIds: roles}).then(rsp => {
              this.$message.success('创建成功')
              this.$emit('set-visible', false)
              this.$emit('refresh-data')
              this.$refs['ruleForm'].resetFields()
              setTimeout(() => { this.confirmLoading = false }, 1000)
            }).catch(() => {
              this.confirmLoading = false
            })
          }
        }
      })
    }
  },
  watch: {
    visible () {
      if (this.visible) {
        this.roleOptTitle = this.isView ? '查看角色' : (!this.editRoleId ? '创建角色' : '编辑角色')
        queryRoleDetail({roleId: this.editRoleId}).then(rsp => {
          this.form.name = rsp.data.name

          const pids = rsp.data.powerIds
          if (this.isView) {
            this.form.powerIds = pids.split(',').map(v => parseInt(v))
          } else {
            this.form.powerIds = checkedPowerIds(pids, rsp.data.powerList)
          }

          let tree = this.handleTree([], rsp.data.powerList)
          this.treeData = tree
        })
      }
    }
  }
}
</script>

<style lang="less" scoped>

</style>
